package com.xxl.job.executor.service.jobhandler;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.bizsys.domain.CreditAccount;
import com.ruoyi.bizsys.domain.LoanDeferredOrder;
import com.ruoyi.bizsys.domain.MonitorLog;
import com.ruoyi.bizsys.service.ICreditAccountService;
import com.ruoyi.bizsys.service.ILoanDeferredOrderService;
import com.ruoyi.bizsys.service.IMonitorLogService;
import com.ruoyi.business.common.AsyncService;
import com.ruoyi.business.service.IBRepaymentService;
import com.ruoyi.business.service.IBatchDateJobService;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.executor.service.AsyncBizService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * 卡余额代扣
 */
@Component
@Slf4j
public class CardBatchPartialDebitJob {
    @Autowired
    IBatchDateJobService batchDateJobService;
    @Autowired
    IBRepaymentService bRepaymentService;
    @Autowired
    ICreditAccountService creditAccountService;
    @Autowired
    RedisCache redisCache;
    @Autowired
    AsyncBizService asyncBizService;
    @Autowired
    ILoanDeferredOrderService loanDeferredOrderService;
    @Autowired
    AsyncService asyncService;
    @Autowired
    IMonitorLogService iMonitorLogService;

    @XxlJob("cardBatchPartialDebitJobHandler")
    public void execute() {
        String custNo = XxlJobHelper.getJobParam();
        XxlJobHelper.log("银行卡批量余额代扣 Start >>>>>>>>>>");
        if (!StringUtils.isBlank(custNo)) {
            dealByOne(custNo);
            return;
        }
        List<CreditAccount> accountList = creditAccountService.getOnLoanCreditAccountsHasCard();
        int accountCount = accountList.size();
        if (accountCount <= 0) {
            XxlJobHelper.log("银行卡批量余额代扣 End >>>>>>>>>> 无待处理的在贷客户");
        }

        XxlJobHelper.log("银行卡批量余额代扣 ing >>>>>>>>>> accountList.size():" + accountCount);

        deal(accountList);

        XxlJobHelper.log("银行卡批量余额代扣 End >>>>>>>>>>");
    }

    private void dealByOne(String custNo) {
        log.info("银行卡批量余额代扣 测试单用户 >>>>>>>>>>" + custNo);
        CreditAccount account = creditAccountService.getByCustNo(custNo);
        try {
            asyncBizService.dealIouCardWithhold(account);
        } catch (Exception e) {
            log.info("service执行出错");
        }
        log.info("service 结束----->");
    }

    public void deal(List<CreditAccount> accountList) {
        int faildCount = 0;
        long l = System.currentTimeMillis();
        List<Future> result = new ArrayList<>();
        try {
            for (CreditAccount account : accountList) {
                log.info("客户号 {} 开始执行余额代扣操作", account.getCustNo());
                // 检查借据是否有处理中的延期订单
                if (doNotHaveDefering(account.getCustNo())) {
                    TimeUnit.MILLISECONDS.sleep(180);
                    Future<String> integerFuture = asyncBizService.dealIouCardWithhold(account);
                    result.add(integerFuture);
                }
                log.info("客户号 {} 执行批扣余额代扣正常结束", account.getCustNo());
            }
            for (Future future : result) {
                try {
                    future.get(50, TimeUnit.SECONDS);
                } catch (Exception e) {
                    faildCount++;
                }
            }
            sendTofeishu(accountList.size(), faildCount);

        } catch (Exception e) {
            log.error("PartialDebit service 执行出错", e);
        }
        log.info("service 结束----->用时: {}, all:{}, faildCount: {}", (System.currentTimeMillis() - l), result.size(), faildCount);
    }

    private void sendTofeishu(int size, int faildCount) {
        MonitorLog monitorLog = new MonitorLog();
        monitorLog.setApiName("CardBatchPartialDebitJob");
        monitorLog.setLogContent(faildCount + " / " + size);
        monitorLog.setFirstTime(DateUtils.getTime());
        monitorLog.setName("monitor-group");
        monitorLog.setSerialNumber(IdUtils.reqId());

        JSONObject content = new JSONObject();
        content.put("ClassName", "CardBatchPartialDebitJob");
        content.put("Time", new Date());
        content.put("CountNums", size);
        content.put("FailNums", faildCount);
        monitorLog.setContent(content.toString());
        iMonitorLogService.insertMonitorLog(monitorLog);
        content.put("LogNumber", monitorLog.getId());
        asyncService.sendFeishu("CardBatchPartialDebitJob", "BatchJobError", content);
    }


    private boolean doNotHaveDefering(String custNo) {
        log.info("客户号{}开始执行余额代扣操作:查询是否存在处理中的延期订单", custNo);
        // 检查是否存在延期中的订单
        LoanDeferredOrder loanDeferredOrder = loanDeferredOrderService.getOne(new QueryWrapper<LoanDeferredOrder>()
                .eq("cust_no", custNo)
                .eq("status", LoanDeferredOrder.STATUS_WAIT)
                .last("limit 1")
        );
        if (null != loanDeferredOrder) {
            log.info("客户号{}开始执行余额代扣操作,查询是否存在处理中的延期订单:存在！", custNo);
            return false;
        }
        log.info("客户号{}开始执行余额代扣操作,查询是否存在处理中的延期订单:不存在！", custNo);
        return true;
    }


}
